﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BreukADO.Model
{
    class BreukContainer
    {
        protected int teller;
        protected List<Breuk> breuken;

        /// <summary>
        /// Constructor
        /// </summary>
        public BreukContainer()
        {
            breuken = new List<Breuk>();
            teller = 0;
        }

        /// <summary>
        /// Methode om een Breuk toe te voegen
        /// </summary>
        /// <param name="breuk">Breuk</param>
        public virtual void AddBreuk(Breuk breuk)
        {
            breuken.Add(breuk);
            teller++;
        }

        /// <summary>
        /// Methode om meerdere Breuken tegelijk toe te voegen
        /// </summary>
        /// <param name="b">Breuk-array</param>
        public void AddBreuk(params Breuk[] b)
        {
            for (int i = 0; i < b.Length; i++)
            {
                breuken.Add(b[i]);
                teller++;
            }
        }

        /// <summary>
        /// Methode om alle Breuken te tonen
        /// </summary>
        /// <returns>String</returns>
        public String Toonbreuken()
        {
            String res = "";
            foreach (Breuk b in breuken)
            {
                res += b.Toon() + "\n";
            }
            return res;
        }

        /// <summary>
        /// Methode om Breuken op te tellen
        /// </summary>
        /// <returns>Breuk</returns>
        public Breuk TelOp()
        {
            Breuk b = breuken[0];
            for (int i = 1; i < breuken.Count; i++)
            {
                b += breuken[i];
            }
            return b;
        }

        /// <summary>
        /// Methode om de optelling van de Breuken te tonen
        /// </summary>
        /// <param name="p">Precisie</param>
        /// <returns>String</returns>
        public String ToonTelOp(int p)
        {
            string res = "";
            for (int i = 0; i < breuken.Count; i++)
            {
                if (i == breuken.Count - 1)
                {
                    res += breuken[i].Toon() + " = ";
                }
                else
                {
                    res += breuken[i].Toon() + " + ";
                }
            }
            res += TelOp().Toon() + " = " + TelOp().ToonDecimaal(p);
            return res;
        }

        /// <summary>
        /// Methode om Breuken af te trekken
        /// </summary>
        /// <returns>Breuk</returns>
        public Breuk TrekAf()
        {
            Breuk b = breuken[0];
            for (int i = 1; i < breuken.Count; i++)
            {
                b -= breuken[i];
            }
            return b;
        }

        /// <summary>
        /// Methode om de aftrekking van de Breuken te tonen
        /// </summary>
        /// <param name="p">Precisie</param>
        /// <returns>String</returns>
        public String ToonTrekAf(int p)
        {
            string res = "";
            for (int i = 0; i < breuken.Count; i++)
            {
                if (i == breuken.Count - 1)
                {
                    res += breuken[i].Toon() + " = ";
                }
                else
                {
                    res += breuken[i].Toon() + " - ";
                }
            }
            res += TrekAf().Toon() + " = " + TrekAf().ToonDecimaal(p);
            return res;
        }

        /// <summary>
        /// Methode om de Breuken te vermenigvuldigen
        /// </summary>
        /// <returns>Breuk</returns>
        public Breuk Vermenigvuldig()
        {
            Breuk b = breuken[0];
            for (int i = 1; i < breuken.Count; i++)
            {
                b *= breuken[i];
            }
            return b;
        }

        /// <summary>
        /// Methode om de vermenigvuldiging van de Breuken
        /// </summary>
        /// <param name="p">Precisie</param>
        /// <returns>String</returns>
        public String ToonVermenigvuldig(int p)
        {
            string res = "";
            for (int i = 0; i < breuken.Count; i++)
            {
                if (i == breuken.Count - 1)
                {
                    res += breuken[i].Toon() + " = ";
                }
                else
                {
                    res += breuken[i].Toon() + " * ";
                }
            }
            res += Vermenigvuldig().Toon() + " = " + Vermenigvuldig().ToonDecimaal(p);
            return res;
        }

        /// <summary>
        /// Methode om Breuken te delen
        /// </summary>
        /// <returns>Breuk</returns>
        public Breuk Delen()
        {
            Breuk b = breuken[0];
            for (int i = 1; i < breuken.Count; i++)
            {
                b /= breuken[i];
            }
            return b;
        }

        /// <summary>
        /// Methode om de delingen van de Breuken te tonen
        /// </summary>
        /// <param name="p">Precisie</param>
        /// <returns>String</returns>
        public String ToonDelen(int p)
        {
            string res = "";
            for (int i = 0; i < breuken.Count; i++)
            {
                if (i == breuken.Count - 1)
                {
                    res += breuken[i].Toon() + " = ";
                }
                else
                {
                    res += breuken[i].Toon() + " / ";
                }
            }
            res += Delen().Toon() + " = " + Delen().ToonDecimaal(p);
            return res;
        }

        /// <summary>
        /// Methode om Breuken in volgorde van creatie te tonen
        /// </summary>
        /// <returns>String</returns>
        public String ToonCreatie()
        {
            return ToonList(this.Breuken);
        }

        /// <summary>
        /// Sorteer de Breuken van klein naar groot
        /// </summary>
        /// <param name="list">Breuken-list</param>
        private void SortKleinGroot(List<Breuk> list)
        {
            list.Sort(new BreukComparerKleinGroot());
        }

        /// <summary>
        /// Sorteer de Breuken van groot naar klein
        /// </summary>
        /// <param name="list">Breuken-list</param>
        private void SortGrootKlein(List<Breuk> list)
        {
            list.Sort(new BreukComparerGrootKlein());
        }

        /// <summary>
        /// Toon de lijst van Breuken
        /// </summary>
        /// <param name="list">Breuken-list</param>
        /// <returns>String</returns>
        private String ToonList(List<Breuk> list)
        {
            string res = "";
            for (int i = 0; i < list.Count; i++)
            {
                res += breuken[i].Toon() + " ";
            }
            return res;
        }

        /// <summary>
        /// Toon de Breuken van klein naar groot
        /// </summary>
        /// <returns>String</returns>
        public String ToonKleinGroot()
        {
            List<Breuk> copy = this.Breuken;
            SortKleinGroot(copy);
            return ToonList(copy);
        }

        /// <summary>
        /// Toon de Breuken van groot naar klein
        /// </summary>
        /// <returns>String</returns>
        public String ToonGrootKlein()
        {
            List<Breuk> copy = this.Breuken;
            SortGrootKlein(copy);
            return ToonList(copy);
        }

        /// <summary>
        /// Getter & Setter Verzameling Breuken
        /// </summary>
        /// <param name="index">index</param>
        /// <returns>Breuk</returns>
        public Breuk this[int index]
        {
            get
            {
                return breuken[index];
            }
            set
            {
                Breuk b = value;
                breuken[teller] = b;
                teller++;
            }
        }

        /// <summary>
        /// Getter & Setter Breuken-list
        /// </summary>
        public List<Breuk> Breuken
        {
            get { return breuken; }
            set { breuken = value; }
        }

        /// <summary>
        /// Aantal Breuken in de container
        /// </summary>
        /// <returns>Aantal Breuken</returns>
        public int AantalBreuken()
        {
            return teller;
        }

    }
}
